package com.fowo.api.sys.service.impl;

import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.sys.service.FileExtHandler;
import com.fowo.api.sys.service.FileStorageService;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Map;

/**
 * 重设图片文件大小扩展处理器
 * @author yl_ls
 */
@Slf4j
@Component
public class ResizeFileExtHandler implements FileExtHandler {
    @Resource
    private Map<String, FileStorageService> fileStorageServiceMap;

    @Override
    public String name() {
        return "resize";
    }

    @Override
    public String run(SysFile sysFile, String[] args) throws Exception {
        // 最大宽度
        Integer maxWidth = parseIntegerArg(args, "mw");
        // 最大高度
        Integer maxHeight = parseIntegerArg(args, "mh");
        // 固定缩放
        Float scale = parseFloatArg(args, "s");

        if (maxHeight == null && maxWidth == null && scale == null) {
            throw new Exception("使用 resize 扩展处理程序必须提供 mw,mh,scale 参数之一");
        }

        // 按参数生成文件名后缀
        String fn = sysFile.getStorageKey();

        // 获取附件
        FileStorageService fileStorageService = getStorageService(sysFile.getStorageType());
        ByteArrayOutputStream rawOs = new ByteArrayOutputStream();
        try(InputStream rawIs = fileStorageService.read(sysFile.getStorageKey())) {
            StreamUtils.copy(rawIs, rawOs);
        }

        // 尺寸重设
        ByteArrayOutputStream resizeOs = new ByteArrayOutputStream();
        ByteArrayInputStream rawBytes = new ByteArrayInputStream(rawOs.toByteArray());
        Thumbnails.Builder<? extends InputStream> builder = Thumbnails.of(rawBytes);
        if (scale != null) {
            builder.scale(scale);
        }
        else if (maxWidth != null && maxHeight != null) {
            builder.size(maxWidth, maxHeight);
        }
        else if (maxWidth != null) {
            builder.width(maxWidth);
        }
        else {
            builder.height(maxHeight);
        }
        builder.toOutputStream(resizeOs);

        // 上传处理好的文件流
        String resizeStorageKey = fileStorageService.write(fn, new ByteArrayInputStream(resizeOs.toByteArray()));
        log.debug("resize 命令处理完成，上传到 {}", resizeStorageKey);

        return String.format("resized:%s,storageKey=%s", String.join(",", args), resizeStorageKey);
    }

    private FileStorageService getStorageService(String storageType) {
        return fileStorageServiceMap.get(storageType);
    }
}
